﻿using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Microsoft.SharePoint.Workflow;
using System.Net;
using System.IO;
using net.windward.api.csharp;
using Microsoft.SharePoint;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.Odbc;
using System.Data.OleDb;
using System.Data;
using System.Net.Mail;
using ArrowWebParts;

namespace net.Windward.WorkflowActions
{
    /// <summary>
    /// A SharePoint Workflow Activity that generates Windward Reports.
    /// </summary>
	public partial class RunReportActivity: Activity
	{
        private const string RPT_DOCX = "DOCX";
        private const string RPT_SML = "SML";
        private const string RPT_PDF = "PDF";
        private const string RPT_PPTX = "PPTX";
        private const string RPT_RTF = "RTF";
        private const string RPT_WML = "WML";
        private const string RPT_XLS = "XLS";
        private const string RPT_XLSX = "XLSX";
        private const string RPT_HTML = "HTML";

		public RunReportActivity()
		{
			InitializeComponent();
		}

        /// <summary>
        /// Generates Windward Reports.
        /// </summary>
        /// <param name="executionContext"></param>
        /// <returns></returns>
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            // history logger
            ISharePointService historyLogger = (ISharePointService)executionContext.GetService(typeof(ISharePointService));
            historyLogger.LogToHistoryList(this.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, -1, TimeSpan.MinValue,
                "Comment", "Executing RunReportActivity", string.Empty);

            // load the license
            string sLic = ArrowLicenseHandler.ReadLicense();
            ArrowLicenseHandler.LoadJavaLicenseProperty(sLic);

            // get the report definition
            ReportDefinition rptDef = getReportDef(historyLogger);

            // get the report data source info
            DataDefinition[] dataSources = rptDef.getDataSources();
            
            // initialize windward engine
            Report.Init();

            // process the run-for query
            DataTable runForQueryDataTable = processRunForQuery();

            // generate the reports
            int timesToRun = Math.Max(1, runForQueryDataTable.Rows.Count);
            // debug history comment
            historyLogger.LogToHistoryList(this.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, -1, TimeSpan.MinValue,
            "Comment", "Running " + timesToRun.ToString() + " reports", string.Empty);
            for (int runNum = 0; runNum < timesToRun; runNum++)
            {
                // debug history comment
                historyLogger.LogToHistoryList(this.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, -1, TimeSpan.MinValue,
                "Comment", "Running report number: " + (runNum+1).ToString(), string.Empty);

                // get the current DataRow
                DataRow runForRecord = runForQueryDataTable.Rows.Count > 0 ? runForQueryDataTable.Rows[runNum] : null;

                // generate a windward report
                Stream templateStream = getStreamFromUrl(rptDef.template);
                Stream reportStream = new MemoryStream();
                Report reportGen = createReport(templateStream, reportStream, OutputFormat);
                runReport(rptDef, dataSources, runForRecord, reportStream, reportGen);

                // create report file name
                string reportFileName = "WRWorkflowRpt_" + (runNum + 1).ToString() + getFileExtension(OutputFormat);

                // write the report to the report doc lib
                uploadReportToSP(reportStream, reportFileName, historyLogger);

                // send email
                emailReport(reportStream, reportFileName, runForRecord, historyLogger);
            }

            // done.
            return ActivityExecutionStatus.Closed;
        }

        /// <summary>
        /// Emails the report to the email list specified in the workflow configuration.
        /// </summary>
        /// <param name="reportStream"></param>
        /// <param name="reportFileName"></param>
        /// <param name="historyLogger"></param>
        private void emailReport(Stream reportStream, string reportFileName, DataRow runForRecord,
            ISharePointService historyLogger)
        {
            if (string.IsNullOrEmpty(MailServer))
                return;
            try
            {
                // map email to run-for query column
                string to = Boolean.Parse(IsMapEmailCol) ? (string)runForRecord[RunForEmail] : RunForEmail;

                // reset the stream caret
                if (reportStream.CanSeek)
                    reportStream.Seek(0, SeekOrigin.Begin);

                // get the smtp server
                SmtpClient smtp = new SmtpClient(MailServer);

                // create the message
                MailMessage msg = new MailMessage();
                msg.To.Add(to);
                msg.From = new MailAddress(MailFrom);
                msg.Subject = MailSubject;
                msg.Body = MailBody;
                msg.Attachments.Add(new Attachment(reportStream, reportFileName));

                // send the email
                smtp.Send(msg);
            }
            catch (Exception ex)
            {
                historyLogger.LogToHistoryList(this.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, -1, TimeSpan.MinValue,
                "Error", "There was an error sending email.\n" + ex.Source + "\n" + ex.Message + "\n" + ex.StackTrace, string.Empty);
            }
        }

        /// <summary>
        /// Gets the report definition.
        /// </summary>
        /// <param name="historyLogger">the history logger</param>
        /// <returns>the report definition</returns>
        private ReportDefinition getReportDef(ISharePointService historyLogger)
        {
            // get the report definition
            historyLogger.LogToHistoryList(this.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, -1, TimeSpan.MinValue,
                "Comment", "Executing RunReportActivity", string.Empty);
            if (ReportDefinition == null)
            {
                historyLogger.LogToHistoryList(this.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, -1, TimeSpan.MinValue,
                "Error", "Null report definition URL", string.Empty);
                throw new ArgumentException("An internal error caused the report definition url to be null in the " + this.Name + " activity.");
            }
            if (ReportDefinition.Equals(string.Empty))
            {
                historyLogger.LogToHistoryList(this.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, -1, TimeSpan.MinValue,
                "Error", "Empty report definition URL", string.Empty);
                throw new ArgumentException("An internal error caused the report definition url to be empty in the " + this.Name + " activity.");
            }
            historyLogger.LogToHistoryList(this.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, -1, TimeSpan.MinValue,
                "Comment", "Report definition URL: " + ReportDefinition, string.Empty);
            ReportDefinition rai = new ReportDefinition(ReportDefinition);
            historyLogger.LogToHistoryList(this.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, -1, TimeSpan.MinValue,
            "Comment", "Report definition parsed", string.Empty);
            return rai;
        }

        /// <summary>
        /// Runs the specified windward Report.  Requires a new Report object for each call.  
        /// Runs ProcessSetup, ProcessData, ProcessComplete, and Dispose on the Report.
        /// </summary>
        /// <param name="rai">the report definition for this report</param>
        /// <param name="rdsi">the data source info collection for this report</param>
        /// <param name="rowOn">the run-for query record for this report</param>
        /// <param name="reportStream">the report stream</param>
        /// <param name="reportGen">the Report object</param>
        private void runReport(ReportDefinition rai, DataDefinition[] rdsi, DataRow runForRecord, 
            Stream reportStream, Report reportGen)
        {
            // initialize the report gen
            reportGen.ProcessSetup();

            // map parameters
            KeyPairDictionary map = getMap(rai, runForRecord);

            // process the data
            for (int i = 0; i < rdsi.Length; i++)
            {
                IReportDataSource irds = rdsi[i].createIReportDataSource();
                if (map.Count > 0)
                    irds.Map = map;
                reportGen.ProcessData(irds, rai.dataSourceNameArray[i]);
            }

            // finish processing the report
            reportGen.ProcessComplete();
            reportStream.Flush();
            reportGen.Dispose();
        }

        /// <summary>
        /// Uploads the specified Stream to the save-in document library.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="fileName"></param>
        /// <param name="historyLogger">the history logger</param>
        private void uploadReportToSP(Stream stream, string fileName, ISharePointService historyLogger)
        {
            if (SaveInSiteUrl == null)
            {
                historyLogger.LogToHistoryList(this.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, -1, TimeSpan.MinValue,
                    "Error", "Null save-in site url", string.Empty);
                throw new ArgumentException("An internal error caused the url of the site that the report would be saved in to be null in the " + this.Name + " activity.");
            }
            if (SaveInSiteUrl.Equals(string.Empty))
            {
                historyLogger.LogToHistoryList(this.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, -1, TimeSpan.MinValue,
                    "Error", "Empty save-in site url", string.Empty);
                throw new ArgumentException("An internal error caused the url of the site that the report would be saved in to be empty in the " + this.Name + " activity.");
            }
            SPSite tempSite = new SPSite(SaveInSiteUrl); //added by enjayh
            SPUserToken user = tempSite.SystemAccount.UserToken; //added by enjayh
            SPSite siteCollection = new SPSite(SaveInSiteUrl, user); //modified by enjayh from SPSite siteCollection = new SPSite(SaveInSiteUrl);
            SPWeb site = siteCollection.AllWebs[""]; // bugbug: comment what this line is for
            if (SaveInDocLibUrl == null)
            {
                historyLogger.LogToHistoryList(this.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, -1, TimeSpan.MinValue,
                    "Error", "Null save-in document library url", string.Empty);
                throw new ArgumentException("An internal error caused the url of the document library that the report would be saved in to be null in the " + this.Name + " activity.");
            }
            if (SaveInDocLibUrl.Equals(string.Empty))
            {
                historyLogger.LogToHistoryList(this.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, -1, TimeSpan.MinValue,
                    "Error", "Empty save-in document library url", string.Empty);
                throw new ArgumentException("An internal error caused the url of the document library that the report would be saved in to be empty in the " + this.Name + " activity.");
            }
            SPDocumentLibrary reportDocLib = (SPDocumentLibrary)site.GetList(SaveInDocLibUrl);
            string reportLibRelPath = reportDocLib.RootFolder.ServerRelativeUrl;
            string reportLibPath = siteCollection.MakeFullUrl(reportLibRelPath);
            string reportPath = reportLibPath + "/" + fileName;
            site.Files.Add(reportPath, stream, true);
        }

        /// <summary>
        /// Downloads the data from the specified URL using CredentialCache.DefaultNetworkCredentials,
        /// and returns the data in a Stream.
        /// </summary>
        /// <param name="templateUrl"></param>
        /// <returns>the data downloaded from the specified URL</returns>
        private Stream getStreamFromUrl(string url)
        {
            WebClient client = new WebClient();
            client.Credentials = CredentialCache.DefaultNetworkCredentials;
            return client.OpenRead(url);
        }

        /// <summary>
        /// Creates the appropriate Report for the specified output format
        /// </summary>
        /// <param name="templateStream"></param>
        /// <param name="reportStream"></param>
        /// <param name="outFormat">One of the RPT_* strings</param>
        /// <returns>the appropriate Report for the specified output format</returns>
        private Report createReport(Stream templateStream, Stream reportStream, string outFormat)
        {
            switch (outFormat)
            {
                case RPT_DOCX:
                    return new ReportDocx(templateStream, reportStream);
                case RPT_PDF:
                    return new ReportPdf(templateStream, reportStream);
                case RPT_PPTX:
                    return new ReportPptx(templateStream, reportStream);
                case RPT_RTF:
                    return new ReportRtf(templateStream, reportStream);
                case RPT_SML:
                    return new ReportSpreadML(templateStream, reportStream);
                case RPT_WML:
                    return new ReportWordML(templateStream, reportStream);
                case RPT_XLS:
                    return new ReportXls(templateStream, reportStream);
                case RPT_XLSX:
                    return new ReportXlsx(templateStream, reportStream);
                default:
                    throw new ArgumentException("Invalid report format: " + outFormat);
            }
        }

        /// <summary>
        /// Gets the file extension (.docx, .pdf, ...) for the specified output
        /// </summary>
        /// <param name="outFormat">One of the RPT_* strings</param>
        /// <returns>the file extension (.docx, .pdf, ...) for the specified output</returns>
        private string getFileExtension(string outFormat)
        {
            switch (outFormat)
            {
                case RPT_DOCX:
                    return ".docx";
                case RPT_PDF:
                    return ".pdf";
                case RPT_PPTX:
                    return ".pptx";
                case RPT_RTF:
                    return ".rtf";
                case RPT_SML:
                    return ".xml";
                case RPT_WML:
                    return ".xml";
                case RPT_XLS:
                    return ".xls";
                case RPT_XLSX:
                    return ".xlsx";
                default:
                    throw new ArgumentException("Invalid report format: " + outFormat);
            }
        }

        /// <summary>
        /// Gets a DataTable for the run-for query, or null if a run-for is not being used
        /// </summary>
        /// <returns></returns>
        private DataTable processRunForQuery()
        {
            DataTable dataTable = new DataTable();

            if (string.IsNullOrEmpty(RunForQuery))
                return dataTable;

            // determine the adapter type
            switch (RunForAdapter)
            {
                case "MS SQL":
                    SqlConnection sqlConn = new SqlConnection(RunForConnStr);
                    SqlDataAdapter sqlAdapter = new SqlDataAdapter(RunForQuery, sqlConn);
                    sqlAdapter.Fill(dataTable);
                    sqlConn.Close();
                    return dataTable;
                case "ODBC":
                    OdbcConnection odbcConn = new OdbcConnection(RunForConnStr);
                    OdbcDataAdapter odbcAdapter = new OdbcDataAdapter(RunForQuery, odbcConn);
                    odbcAdapter.Fill(dataTable);
                    odbcConn.Close();
                    return dataTable;
                case "OLEDB":
                    OleDbConnection oledbConn = new OleDbConnection(RunForConnStr);
                    OleDbDataAdapter oledbAdapter = new OleDbDataAdapter(RunForQuery, oledbConn);
                    oledbAdapter.Fill(dataTable);
                    oledbConn.Close();
                    return dataTable;
                default:
                    throw new ArgumentException("Invalid adapter type: " + RunForAdapter + ".");
            }
        }

        /// <summary>
        /// Generates a KeyPairDictionary for windward parameter map.
        /// </summary>
        /// <param name="rai">a report definition</param>
        /// <param name="runForRecord">the current data row from the run-for query or null if none</param>
        /// <returns>KeyPairDictionary for windward parameter map</returns>
        private KeyPairDictionary getMap(ReportDefinition rai, DataRow runForRecord)
        {
            KeyPairDictionary map = new KeyPairDictionary();

            string[] parameters = getParameters();
            if (parameters == null)
                return map;
            try
            {
                // NOTE: the last strParm is always string.Empty, so we skip it
                for (int parmInd = 0; parmInd < parameters.Length - 1; parmInd++)
                {
                    // get the raw type:key=value string
                    string strParm = parameters[parmInd];

                    // extract the type
                    int posCol = strParm.IndexOf(':');
                    string strType = strParm.Substring(0, posCol);

                    // extract the name
                    int posEq = strParm.IndexOf('=');
                    string strKey = strParm.Substring(posCol + 1, posEq - posCol - 1);

                    // extract the value
                    int posCol2 = strParm.IndexOf(':', posCol + 1);
                    string strValue = strParm.Substring(posEq + 1, posCol2 - posEq - 1);

                    // extract the map-to-column value
                    string strMapToCol = strParm.Substring(posCol2 + 1);
                    bool isMapToCol = Boolean.Parse(strMapToCol);

                    // create the new map item
                    Object value;
                    if (!isMapToCol)
                    {
                        switch (strType)
                        {
                            case "DATE":
                                value = Convert.ToDateTime(strValue);
                                break;
                            case "INTEGER":
                                value = Convert.ToInt64(strValue);
                                break;
                            case "NUMBER":
                                value = Convert.ToDouble(strValue);
                                break;
                            default:
                                value = strValue;
                                break;
                        }
                    }
                    else
                    {
                        value = runForRecord[strValue];
                    }
                    map.Add(strKey, value);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("An error occured while building the parameter map.", ex);
            }
            return map;
        }

        /// <summary>
        /// Parses parameter xml and returns an array of parameter strings
        /// </summary>
        /// <returns>an array of "type:key=value" strings</returns>
        private string[] getParameters()
        {
            return ParameterXml.Split(';');
        }

        protected override ActivityExecutionStatus HandleFault(ActivityExecutionContext executionContext, Exception exception)
        {
            ISharePointService historyLogger = (ISharePointService)executionContext.GetService(typeof(ISharePointService));
            string histMessage = String.Format("There was an error in the RunReportActivity. \n{0}\n{1}\n{2}", 
                exception.Message,
                exception.Source,
                exception.StackTrace);
            historyLogger.LogToHistoryList(this.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowError, -1, TimeSpan.MinValue,
                "Error", histMessage, string.Empty);
            return base.HandleFault(executionContext, exception);
        }


        #region Dependency Properties
        /// <summary>
        /// Used to get the URL of the report definition.
        /// </summary>
        public static DependencyProperty ReportDefinitionProperty =
            DependencyProperty.Register("ReportDefinition", typeof(string), typeof(RunReportActivity));
        /// <summary>
        /// Used to get the URL of the site where the report will be saved.
        /// </summary>
        public static DependencyProperty SaveInSiteUrlProperty =
            DependencyProperty.Register("SaveInSiteUrl", typeof(string), typeof(RunReportActivity));
        /// <summary>
        /// Used to get the URL of the document library where the report will be saved.
        /// </summary>
        public static DependencyProperty SaveInDocLibUrlProperty =
            DependencyProperty.Register("SaveInDocLibUrl", typeof(string), typeof(RunReportActivity));
        /// <summary>
        /// Used to get the parameters for the report.
        /// </summary>
        public static DependencyProperty ParameterXmlProperty =
            DependencyProperty.Register("ParameterXml", typeof(string), typeof(RunReportActivity));
        /// <summary>
        /// Used to get the run-for query for the report.
        /// </summary>
        public static DependencyProperty RunForQueryProperty =
            DependencyProperty.Register("RunForQuery", typeof(string), typeof(RunReportActivity));
        /// <summary>
        /// Used to get the run-for query's connection string.
        /// </summary>
        public static DependencyProperty RunForConnStrProperty =
            DependencyProperty.Register("RunForConnStr", typeof(string), typeof(RunReportActivity));
        /// <summary>
        /// Used to get the adapter type of the run-for query.
        /// </summary>
        public static DependencyProperty RunForAdapterProperty =
            DependencyProperty.Register("RunForAdapter", typeof(string), typeof(RunReportActivity));
        /// <summary>
        /// Used to get the email to send the report to.
        /// </summary>
        public static DependencyProperty RunForEmailProperty =
            DependencyProperty.Register("RunForEmail", typeof(string), typeof(RunReportActivity));
        /// <summary>
        /// Used to determine if the email comes from a column.
        /// </summary>
        public static DependencyProperty IsMapEmailColProperty =
            DependencyProperty.Register("IsMapEmailCol", typeof(string), typeof(RunReportActivity));
        /// <summary>
        /// Used to get the output format for the report.
        /// </summary>
        public static DependencyProperty OutputFormatProperty =
            DependencyProperty.Register("OutputFormat", typeof(string), typeof(RunReportActivity));
        /// <summary>
        /// Used to get the mail server.
        /// </summary>
        public static DependencyProperty MailServerProperty =
            DependencyProperty.Register("MailServer", typeof(string), typeof(RunReportActivity));
        /// <summary>
        /// Used to get the mail from address.
        /// </summary>
        public static DependencyProperty MailFromProperty =
            DependencyProperty.Register("MailFrom", typeof(string), typeof(RunReportActivity));
        /// <summary>
        /// Used to get the mail subject.
        /// </summary>
        public static DependencyProperty MailSubjectProperty =
            DependencyProperty.Register("MailSubject", typeof(string), typeof(RunReportActivity));
        /// <summary>
        /// Used to get the mail body.
        /// </summary>
        public static DependencyProperty MailBodyProperty =
            DependencyProperty.Register("MailBody", typeof(string), typeof(RunReportActivity));
        #endregion


        #region Actual Properties
        /// <summary>
        /// The URL of the report definition.
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [Description("Enter the URL of the report definition")]
        public string ReportDefinition 
        {
            get
            {
                return ((string)(base.GetValue(ReportDefinitionProperty)));
            }
            set
            {
                base.SetValue(ReportDefinitionProperty, value);
            }
        }

        /// <summary>
        /// The URL of the site that the report will be saved in.
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [Description("Enter the URL of the site that the report will be saved in")]
        public string SaveInSiteUrl 
        {
            get
            {
                return ((string)(base.GetValue(SaveInSiteUrlProperty)));
            }
            set
            {
                base.SetValue(SaveInSiteUrlProperty, value);
            }
        }

        /// <summary>
        /// The URL of the document library that the report will be saved in.
        /// </summary>
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [Description("Enter the URL of the document library that the report will be saved in.")]
        public string SaveInDocLibUrl
        {
            get
            {
                return ((string)(base.GetValue(SaveInDocLibUrlProperty)));
            }
            set
            {
                base.SetValue(SaveInDocLibUrlProperty, value);
            }
        }

        /// <summary>
        /// The parameters for the report.
        /// </summary>
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [Description("Enter the parameters for the report.")]
        public string ParameterXml
        {
            get
            {
                return ((string)(base.GetValue(ParameterXmlProperty)));
            }
            set
            {
                base.SetValue(ParameterXmlProperty, value);
            }
        }

        /// <summary>
        /// The run-for query, which determines how many times to run the report and passes a parameter.
        /// </summary>
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [Description("Enter the run-for query for the report.")]
        public string RunForQuery
        {
            get
            {
                return ((string)(base.GetValue(RunForQueryProperty)));
            }
            set
            {
                base.SetValue(RunForQueryProperty, value);
            }
        }

        /// <summary>
        /// The run-for query's connection string.
        /// </summary>
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [Description("Enter the connection string for the run-for query for the report.")]
        public string RunForConnStr
        {
            get
            {
                return ((string)(base.GetValue(RunForConnStrProperty)));
            }
            set
            {
                base.SetValue(RunForConnStrProperty, value);
            }
        }

        /// <summary>
        /// The run-for adapter.
        /// </summary>
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [Description("Enter the run-for adapter.")]
        public string RunForAdapter
        {
            get
            {
                return ((string)(base.GetValue(RunForAdapterProperty)));
            }
            set
            {
                base.SetValue(RunForAdapterProperty, value);
            }
        }

        /// <summary>
        /// The run-for email address
        /// </summary>
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [Description("Enter the run-for email address.")]
        public string RunForEmail
        {
            get
            {
                return ((string)(base.GetValue(RunForEmailProperty)));
            }
            set
            {
                base.SetValue(RunForEmailProperty, value);
            }
        }

        /// <summary>
        /// Whether run-for email address maps to run-for query column
        /// </summary>
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [Description("Enter true if the email address maps to a run-for query column, otherwise enter false.")]
        public string IsMapEmailCol
        {
            get
            {
                return ((string)(base.GetValue(IsMapEmailColProperty)));
            }
            set
            {
                base.SetValue(IsMapEmailColProperty, value);
            }
        }

        /// <summary>
        /// The output format for the report.  One of the RPT_* strings.
        /// </summary>
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [Description("Enter output format for the report.")]
        public string OutputFormat
        {
            get
            {
                return ((string)(base.GetValue(OutputFormatProperty)));
            }
            set
            {
                base.SetValue(OutputFormatProperty, value);
            }
        }

        /// <summary>
        /// The mail server to use for emailing the reports.
        /// </summary>
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [Description("Enter the mail server that will be used to email reports.")]
        public string MailServer
        {
            get
            {
                return ((string)(base.GetValue(MailServerProperty)));
            }
            set
            {
                base.SetValue(MailServerProperty, value);
            }
        }

        /// <summary>
        /// The mail from address to use for emailing the reports.
        /// </summary>
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [Description("Enter the mail from address that will be used to email reports.")]
        public string MailFrom
        {
            get
            {
                return ((string)(base.GetValue(MailFromProperty)));
            }
            set
            {
                base.SetValue(MailFromProperty, value);
            }
        }

        /// <summary>
        /// The mail subject to use for emailing the reports.
        /// </summary>
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [Description("Enter the mail subject that will be used to email reports.")]
        public string MailSubject
        {
            get
            {
                return ((string)(base.GetValue(MailSubjectProperty)));
            }
            set
            {
                base.SetValue(MailSubjectProperty, value);
            }
        }

        /// <summary>
        /// The mail body to use for emailing the reports.
        /// </summary>
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [Description("Enter the mail body that will be used to email reports.")]
        public string MailBody
        {
            get
            {
                return ((string)(base.GetValue(MailBodyProperty)));
            }
            set
            {
                base.SetValue(MailBodyProperty, value);
            }
        }
        #endregion
    }
}
